<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta
      name="keywords"
      content="HTML,CSS,HTML5,CSS3,ES6,JavaScript,Vue,Vue.js,TS,TypeScript,webpack,前端,全栈,Web开发"
    />
    <meta
      name="description"
      content="一位Web开发工程师的学习、工作笔记-星之痕。
    内容涵盖：HTML,CSS,HTML5,CSS3,ES6,JavaScript,Vue,Vue.js,TS,TypeScript,前端,全栈,Web开发……等"
    />
    <title>vue基础语法-Vue.js 笔记-星之痕</title>

    <style>
      [v-cloak] {
        display: none;
      }

      .hidden {
        display: none;
      }

      .active {
        display: block;
      }

      .normal {
        color: rgb(46, 46, 46);
      }

      .red {
        color: red;
      }

      .inline {
        text-decoration: underline;
      }
      .success {
        color: lightgreen;
      }

      .error {
        color: lightsalmon;
      }
      .aaa {
        color: rgb(189, 97, 199);
      }
      .bbb {
        color: rgb(90, 216, 254);
      }
    </style>
  </head>

  <body>
    <h2>vue2 官方中文文档</h2>
    <h2>vue3 官方中文文档</h2>
    <!-- v-cloak 指令：解决屏幕闪动的方法（当网速过慢，vuejs未能及时加载时会显示vue template源码），或实现延时加载的效果 -->
    <h2>v-cloak 指令：利用样式解决屏幕闪动的方法</h2>
    <div id="app2" v-cloak>
      <h2>{{message}}</h2>
    </div>
    <br />

    <div id="app">
      <h2>插值语法： moustache 语法'{{}}'</h2>
      <h2>{{message}}</h2>
      <!-- v-once 指令：一次性插值指令，类似于单向绑定，后续数据改变时插值处的内容不会更新 -->
      <h2>
        <span v-once>{{message}}</span><br />
        v-once 指令：这个值不会变化

        <button v-on:click="action">点击</button>
        <!-- <button @click='action'>点击</button> -->
      </h2>

      <!-- v-html 指令：输出html标签 -->
      <h2>
        v-html 指令：输出html标签
        <span v-html="sHtml"></span>
      </h2>

      <!-- v-pre 指令：对moustache语法不作解析，输出原本的文本 -->
      <h2>
        v-pre 指令：忽略moustache语法
        <span v-pre>{{message}}</span>
      </h2>

      <!-- v-bind 指令：绑定HTML attribute -->
      <!-- v-bind:attribute 指令简写==> :attribute -->
      <h2>
        v-bind 指令：绑定HTML attribute
        <a v-bind:href="sUrl">链接</a>
        <a :href="sUrl2">百度一下</a>
      </h2>

      <!-- v-bind:绑定class 用法-->
      <h2>
        v-bind 指令：使用 true/false 动态绑定class 对象
        <!-- class={}对象绑定方式 -->
        <span class="normal" v-bind:class="{red:isRed,inline:isInline}"
          >{{message}}</span
        >
        <!-- 函数调用方式fn() -->
        <span class="normal" v-bind:class="getClasses()">{{message}}</span
        ><br />
        <!-- 事件调用方式fn -->
        <button @click="changeStyles">切换样式</button>

        <!-- 巧用索引给数组不同的元素添加不同的class -->
        <!-- <ul>
          <li v-for="(item,index) in books" :key="index" :class="{'aaa':index==0,'bbb':index==1}">
            {{item.name}}
          </li>
        </ul> -->
      </h2>

      <h2>
        v-bind 指令：绑定class 数组
        <!-- 很少这样用，如果class是写死的话，一般直接在class='normal' 里面加 -->
        <span class="normal" v-bind:class="['red','inline']">{{message}}</span>
        <!-- 有可能class是从服务器返回的，这样的话，可以这样写 -->
        <span class="normal" v-bind:class="[styleColor,styleInline]"
          >{{message}}</span
        >
        <!-- 结合三目运算符 -->
        <span class="normal" v-bind:class="[isActive? successClass:errorClass]"
          >{{message}}</span
        >
        <span class="normal" v-bind:class="[isActive? 'success':'error']"
          >{{message}}</span
        >
      </h2>

      <h2>
        v-bind 指令：动态绑定style 样式
        <!-- 凡是有-的style属性名都要变成驼峰式，比如font-size要变成fontSize -->
        <!-- <span class='normal' v-bind:style="{fontSize:'50px',color:'blue'}">{{message}}</span><br> -->
        <span
          class="normal"
          v-bind:style="{fontSize:fontSize+'px',backgroundColor:styleColor}"
          >{{message}}</span
        >
        <span class="normal" :style="getStyles()">{{message}}</span>
        <span class="normal" :style="[baseStyleSize,baseStyleColor]"
          >{{message}}</span
        >
      </h2>

      <!-- 这里属性名不能直接写驼峰或者'-' -->
      <h2>
        v-bind 指令：绑定动态属性
        <a :[myhref]="linkUrl">跳转百度</a>
      </h2>

      <h2>
        computed 计算属性： <span class="normal">{{getFullName()}}</span> |
        <span class="normal">{{fullName}}</span>
      </h2>

      <h2>
        computed 计算属性：reduce计算数组中元素价格
        <span class="normal">总价格1：{{totalPrice}}</span> |
        <span class="normal">总价格2：{{totalPrice2}}</span>
      </h2>
    </div>

    <script src="js/vue.js"></script>
    <script>
      Vue.config.productionTip = false; //阻止vue页面在启动时的生产提示

      setTimeout(() => {
        const app2 = new Vue({
          el: "#app2",
          data() {
            return {
              message: "该内容会在vuejs加载完成后显示!",
            };
          },
        });
      }, 1000);

      const app = new Vue({
        el: "#app",
        data: {
          message: "this is a vue demo!",
          sHtml: `<a href='https://cn.vuejs.org'>链接</a>`,
          sUrl: "https://cn.vuejs.org",
          sUrl2: "https://www.baidu.com",
          isActive: false,
          isRed: true,
          isInline: true,
          successClass: "success",
          errorClass: "error",
          styleColor: "green",
          styleInline: "inline",
          fontSize: 18,
          baseStyleSize: {
            fontSize: "20px",
          },
          baseStyleColor: {
            backgroundColor: "pink",
          },
          firstName: "Lee",
          lastName: "Neo",
          myhref: "href",
          linkUrl: "http://www.baidu.com",
          books: [
            {
              id: 100,
              name: "C语言程序设计",
              price: 15.5,
            },
            {
              id: 101,
              name: "计算机原理",
              price: 23.4,
            },
            {
              id: 102,
              name: "高等数学",
              price: 5.2,
            },
            {
              id: 103,
              name: "Linux系统",
              price: 34.8,
            },
          ],
        },
        computed: {
          fullName: function () {
            return this.firstName + " " + this.lastName;
          },
          totalPrice: function () {
            // arr.reduce(fn(..),0)：计算数组元素相加后的总和==>array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
            // 从这个例子中可以看出reduce()，如果不给初始值，函数中的total默认数组第一个元素,curVlaue为数组第二个元素。
            // 不设初始值方式，当数组元素减少时会导致计算结果不准确，因为curValue不是从第一个元素开始计算导致后面会少一个循环
            return this.books.reduce(function (total, curValue) {
              console.log("totalPrice:" + JSON.stringify(total));
              console.log("curValue:" + JSON.stringify(curValue));
              if (total.price) {
                total = total.price;
              }
              return total + curValue.price;
            });
          },
          // 数组累加推荐使用设置初始值的方式
          totalPrice2: function () {
            return this.books.reduce(function (total, curValue) {
              console.log("totalPrice:" + JSON.stringify(total));
              console.log("curValue:" + curValue.price);
              return total + curValue.price;
            }, 0);
          },
        },
        methods: {
          action: function () {
            this.message = "message的值改变了";
          },
          changeStyles: function () {
            this.isRed = !this.isRed;
            this.isInline = !this.isInline;
          },
          getClasses: function () {
            return {
              red: this.isRed,
              inline: this.isInline,
            };
          },
          getStyles: function () {
            return {
              fontSize: this.fontSize + "px",
              backgroundColor: this.styleColor,
            };
          },
          getFullName: function () {
            return this.firstName + " " + this.lastName;
          },
        },
      });
    </script>
  </body>
</html>
